package spittr.db;

import org.springframework.data.jpa.repository.JpaRepository;
import spittr.domain.Spitter;

import java.util.List;

/**
 * @author XiaoDongLei
 * @Package com.vonzhou.springinaction.knights
 * @date 2018/4/1
 * @Description: Repository interface with operations for {@link Spitter} persistence.
 * 1、编写Spring Data JPA Repository的关键在于要从一组接口中挑选一个进行扩展。
 *
 * 这里，SpitterRepository扩展了Spring Data JPA的JpaRepository（稍后，我会介绍几个其他的接口）。通过这种方式，JpaRepository进行了参数化，所以它就能知道这是一个用来持久化Spitter对象的Repository，并且Spitter的ID类型为Long。另外，它还会继承18个执行持久化操作的通用方法，如保存Spitter、删除Spitter以及根据ID查询Spitter。
 *
 *
 * 让我们回到SpitterRepository接口，它扩展自JpaRepository，而JpaRepository又扩展自Repository标记接口（虽然是间接的）。因此，SpitterRepository就传递性地扩展了Repository接口，也就是Repository扫描时所要查找的接口。当Spring Data找到它后，就会创建SpitterRepository的实现类，其中包含了继承自JpaRepository、PagingAndSortingRepository和CrudRepository的18个方法。
 *
 * 很重要的一点在于Repository的实现类是在应用启动的时候生成的，也就是Spring的应用上下文创建的时候。它并不是在构建时通过代码生成技术产生的，也不是接口方法调用时才创建的。
 *
 * 2、11.3.1　定义查询方法
 * 2.1、实际上，我们并不需要实现findByUsername()。方法签名已经告诉Spring Data JPA足够的信息来创建这个方法的实现了。
 * 当创建Repository实现的时候，Spring Data会检查Repository接口的所有方法，解析方法的名称，并基于被持久化的对象来试图推测方法的目的。本质上，Spring Data定义了一组小型的领域特定语言（domainspecific language DSL），在这里，持久化的细节都是通过Repository方法的签名来描述的。
 *
 * 2.2、Repository方法是由一个动词、一个可选的主题（Subject）、关键词By以及一个断言所组成。在findByUsername()这个样例中，动词是find，断言是Username，主题并没有指定，暗含的主题是Spitter。
 *
 */
public interface SpitterRepository extends JpaRepository<Spitter, Long>, SpitterSweeper {

	Spitter findByUsername(String username);

	List<Spitter> findByUsernameOrFullNameLike(String username, String fullName);

}
